-- LUA中的面向对象编程

-- 定义类的属性
Fighter = {
    name = "",
    health = 0,
    speed = 0
}

-- 定义类的方法
function Fighter:Shoot(times)
    for i = 1, times do
        print("Fighter "..self.name.." shoot at "..self.speed.." speed.")
    end    
end

function Fighter:Bomb()
    print("Fighter "..self.name.." launch BOMB!!!")
end

-- 定义类的构造函数
function Fighter:new(t)
    -- 这是一个语法糖，避免空值，在javascript中也是这么做的
    t = t or {}
    -- 这里就是把metatable设置为self，这就是面向对象的核心。通过metatable来“模拟”一种面向对象
    setmetatable(t, self)
    self.__index  = self
    return t
end

-- 创建对象并使用
local ada = Fighter:new({name="Ada", health=100, speed=60})
-- 这里调用是使用":"而不是"."
ada:Shoot(3)
ada:Bomb()


-- 银行账号例子
BankAccount = {
    account_number = 0,
    holder_name = "",
    balance = 0.0
}

function BankAccount:deposit(amount)
    self.balance = self.balance + amount
end

function BankAccount:withdraw(amount)
    self.balance = self.balance - amount
end

function BankAccount:check()
    print("Bank Account: "..self.holder_name..", Balance:"..self.balance)
end

function BankAccount:new(t)
    t = t or {}
    setmetatable(t, self)
    -- 这东西我没有搞太明白。大概的意思就是你调用[]的时候，比如["deposit"]的时候，怎么确定你自已？这就需要设置__index。
    self.__index = self
    return t
end

-- 使用银行账号
ada = BankAccount:new({account_number=100,holder_name="Ada Wang",balance=0.0})
ada:deposit(1000)
ada:withdraw(100)
ada:check()
-- 直接使用属性
print(ada.holder_name.." have "..ada.balance)